package Logic.Guild;

import FrameWork.EventBus.Anno.Schedule;
import FrameWork.EventBus.Emitter;
import FrameWork.EventBus.EventBusManager;
import FrameWork.EventBus.ITask;
import FrameWork.Model.Player;
import Logic.Guild.Event.ReqJoinGuildEvent;
import Logic.Guild.Event.RespJoinGuildEvent;

import java.util.*;
import java.util.concurrent.ScheduledFuture;

public class Guild implements Emitter {
    private int id;                                             //公会ID
    private int menberLimit;                                    //公会的最大人员数量限制
    private int currentMemberAmount;                            //当前公会的人员数量
    private int joinGold;                                       //加入公会所需要的金钱
    private Map<String,Player> members = new HashMap<>();       //当前的公会的所有成员
    private List<JoinReq> prepareMembers = new LinkedList<>();  //当前正在执行加入公会的成员
    private Queue<Player> waitingQueue = new LinkedList<>();    //等待执行加入公会操作的成员
    private ScheduledFuture monitor;                            //定时任务，定时检查waitingQueue和prepareMembers的状态


    public void joinGuild(ReqJoinGuildEvent event){
        Player player = event.getPlayer();
        //初次请求
        if (event.getMod() == ReqJoinGuildEvent.getReqPartInGuild()){
            if (currentMemberAmount>=menberLimit) {
                responseFullStatus(player);
            }else{
                prepareJoinGuild(player);
            }
        }else if (event.getMod() == ReqJoinGuildEvent.getConsumeResource()){
            if (event.getResult()){
                addMember(player);
            }
        }
    }

    /**
     * 公会添加玩家并通知
     * @param player
     */
    private void addMember(Player player){
        members.put(player.getAccount(),player);
        currentMemberAmount++;
        Iterator<JoinReq> iter = prepareMembers.iterator();
        while (iter.hasNext()){
            if (iter.next().player == player){
                iter.remove();
                break;
            }
        }
        RespJoinGuildEvent resp = new RespJoinGuildEvent(this.getId(),player);
        resp.setMod(RespJoinGuildEvent.FINAL);
        resp.setResult(RespJoinGuildEvent.SUCCESS);
        player.emit("SuccessJoinGuild",resp);
    }

    /**
     * 将Player放进预备添加池
     * @param player
     */
    private void prepareJoinGuild(Player player){
        schedule();
        if (currentMemberAmount<menberLimit){
            if (prepareMembers.size()>=(menberLimit-currentMemberAmount)){
                waitingQueue.add(player);
            }else{
                addPrepareMember(player);
            }
        }
    }

    /**
     * 发送
     * @param player
     */
    private void addPrepareMember(Player player){
        JoinReq req = new JoinReq(player,System.currentTimeMillis());
        prepareMembers.add(req);
        reqConsumeJoinGod(player);
    }

    private void responseFullStatus(Player player){
        RespJoinGuildEvent resp = new RespJoinGuildEvent(this.getId(), player);
        resp.setMod(RespJoinGuildEvent.FINAL);
        resp.setResult(RespJoinGuildEvent.FULL_LOAD);
        player.emit("joinGuildResp",resp);
    }

    private void reqConsumeJoinGod(Player player){
        RespJoinGuildEvent resp = new RespJoinGuildEvent(this.id,player);
        resp.setGold(this.joinGold);
        resp.setMod(RespJoinGuildEvent.REQ_CONSUME_GOLD);
        player.emit("joinGuild",resp);
    }

    public void addGuildMember(Player player){
        EventBusManager.submitTask(getDispatcherCode(),()->{
            addGuildMember0(player);
        });
    }

    private void addGuildMember0(Player player){
        //检查是否满员
        if (currentMemberAmount>menberLimit){
            System.out.println("已经满员");
            return;
        }
        if (currentMemberAmount<menberLimit){
            //如果执行队列满了就添加到waitingQueue中
            if (prepareMembers.size()>=(menberLimit-currentMemberAmount)){
                waitingQueue.add(player);
            }
            else{
                prepareMembers.add(new JoinReq(player,System.currentTimeMillis()));
                //调用player的消费金钱接口
                player.consumeGold(joinGold,ITask.wrap(as->{
                    //该回调会在guild线程执行
                    if (as.isSuccess()){
                        boolean successConsume = as.getValue();
                        if (successConsume){
                            members.put(player.getAccount(),player);
                            currentMemberAmount++;
                            System.out.println(player.getAccount()+"加入公会成功");
                        }else{
                            System.out.println("扣费失败");
                        }
                    }
                    removeReq(player);
                }));
            }
        }
    }

    private void removeReq(Player player){
        Iterator<JoinReq> iter = prepareMembers.iterator();
        while (iter.hasNext()){
            if (iter.next().player == player){
                iter.remove();
                break;
            }
        }
    }

    private void schedule(){
        if (monitor!=null && !monitor.isCancelled()){
            return;
        }
        this.monitor = EventBusManager.submitScheduleTask(500,monitorTask);
    }

    private Runnable monitorTask = new Runnable() {
        @Override
        public void run() {
            //如果当前没有人申请，那么结束循环
            if (waitingQueue.isEmpty() && prepareMembers.isEmpty() && monitor!=null){
                System.out.println("结束循环");
                monitor.cancel(false);
            }
            //TODO 将超时的请求去除
            //尝试从等待队列的玩家添加到准备队列
            int freeSize = menberLimit-prepareMembers.size()-currentMemberAmount;
            if (freeSize>0){
                System.out.println("here");
                while(freeSize>0 && !waitingQueue.isEmpty()){
                    Player player = waitingQueue.poll();
                    addPrepareMember(player);
                    freeSize--;
                }
            }else{
                while(!waitingQueue.isEmpty()){
                    Player player = waitingQueue.poll();
                    responseFullStatus(player);
                }
            }
        }
    };

    public int getId() {
        return id;
    }

    public int getMenberLimit() {
        return menberLimit;
    }

    public int getCurrentMemberAmount() {
        return currentMemberAmount;
    }

    public int getJoinGold() {
        return joinGold;
    }

    public void setId(int id) {
        this.id = id;
    }

    public void setMenberLimit(int menberLimit) {
        this.menberLimit = menberLimit;
    }

    public void setCurrentMemberAmount(int currentMemberAmount) {
        this.currentMemberAmount = currentMemberAmount;
    }

    public void setJoinGold(int joinGold) {
        this.joinGold = joinGold;
    }

    public Map<String, Player> getMembers() {
        return members;
    }

    private class JoinReq{
        Player player;      //申请加入的玩家
        long   reqTime;     //申请加入的时间，即加入prepareMembers的时间

        public JoinReq(Player player, long reqTime) {
            this.player = player;
            this.reqTime = reqTime;
        }
    }

}
